#include<bits/stdc++.h>
using namespace std;
const int N=1002;

int n,m;
char arr[N][N];
int maxn[N][N],minn[N][N];

struct Node{
    int r,c;
    int way,w;
    Node(){}
    Node(int r,int c,int way,int w){
        this->r=r;
        this->c=c;
        this->way=way;
        this->w=w;
    }
    bool operator<(const Node& node) const{
        return w>node.w;
    }
};

struct Node2{
    int r,c;
    int way,w;
    Node2(){}
    Node2(int r,int c,int way,int w){
        this->r=r;
        this->c=c;
        this->way=way;
        this->w=w;
    }
    bool operator<(const Node2& node) const{
        return w<node.w;
    }
};
void dfs(int r,int c,int way,int v){
    if(r>=m) return;
    if(c>=n) return;
    if(arr[r][c]=='#') return;
    if(v<maxn[r][c]) return;
    maxn[r][c]=v;
    if(r==m-1&&c==n-1){
        return;
    }
    for(int i=0;i<=1;i++){
        int w1;
        int r1,c1;
        if(way==i) w1=v;
        else w1=v+1;
        if(i==0){
            r1=r;
            c1=c+1;
        }
        else{
            r1=r+1;
            c1=c;
        }
        int k1;
        if(way==i) k1=v;
        else k1=v+1;
        dfs(r1,c1,i,k1);
    }
}

int main(){
    cin>>m>>n;
    for(int i=0;i<m;i++){
        string str;
        cin>>str;
        for(int j=0;str[j]!='\0';j++){
            arr[i][j]=str[j];
        }
    }
    memset(minn,0x3f,sizeof(minn));
    priority_queue<Node> que;
    que.push(Node(0,0,2,-1));
    minn[0][0]=0;
    while(!que.empty()){
        Node node=que.top();
        que.pop();
        int r=node.r;
        int c=node.c;
        int way=node.way;
        int w=node.w;
        if(w>minn[r][c]) continue;
        //printf("%d %d %d %d\n",r,c,way,w);
        for(int i=0;i<=1;i++){
            int r1,c1;
            //right
            if(i==0) {
                r1=r;
                c1=c+1;
            }
            //down
            if(i==1){
                r1=r+1;
                c1=c;
            }
            if(r1<0||r1>=m) continue;
            if(c1<0||c1>=n) continue;
            if(arr[r1][c1]=='#') continue;
            int w1;
            if(i!=way) w1=w+1;
            else w1=w;
            if(w1<=minn[r1][c1]){
                minn[r1][c1]=w1;
                que.push(Node(r1,c1,i,w1));
            }
        }
    }
    if(minn[m-1][n-1]>3000){
        printf("-1");
        return 0;
    }
    //maxn
    memset(maxn,0xff,sizeof(maxn));
    maxn[0][0]=0;
    priority_queue<Node2> que2;
    que2.push(Node2(0,0,2,0));
    while(!que2.empty()){
        auto node=que2.top();
        que2.pop();
        int rc=node.r,cc=node.c;
        if(node.w<maxn[rc][cc]) continue;
        for(int i=0;i<=1;i++){
            int r1,c1;
            //right
            if(i==0) {
                r1=rc;
                c1=cc+1;
            }
            //down
            if(i==1){
                r1=rc+1;
                c1=cc;
            }
            if(r1<0||r1>=m) continue;
            if(c1<0||c1>=n) continue;
            if(arr[r1][c1]=='#') continue;
            int w1;
            if(i!=node.way) w1=node.w+1;
            else w1=node.w;
            if(w1>maxn[r1][c1]){
                maxn[r1][c1]=w1;
                que2.push(Node2(r1,c1,i,w1));
            }
        }
    }

    printf("%d %d",maxn[m-1][n-1],minn[m-1][n-1]);
    return 0;
}